﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Corecalc;

namespace Sisal
{
    class ExecutionTimes
    {
        private static Dictionary<string, double> simpleExecutionTimeCosts = new Dictionary<string, double> {
            { "+", 1 },
            { "-", 1 },
            { "/", 1.5 },         //Division may be 22 times larger than add, sub, ...
            { "*", 1 },
            { ">", 1 },
            { "<", 1 },
            { ">=", 1 },
            { "<=", 1 },
            { "&", 1 },
            { "<>", 1 },
            { "=", 1 },
            { "IF", 1 },
            { "Const", 0.0 },
            { "Error", 0.0 },
            { "CellRef", 0.0 },
            { "CellArea", 0.0 }
        };

        public static double Get(string op) {
            return simpleExecutionTimeCosts[op];
        }
    }

    class CommunicationCosts
    {
        public static readonly double TSched = 100.0;   //100 cycles
        public static readonly double TMin = 500.0;

        public static readonly Func<double, int> bytesToCycles = cs => (int)Math.Ceiling(cs * 0.125);
        public static readonly Func<int, double> cyclesToBytes = bs => (1.0 / 0.125) * bs;

        //Multiprocessor model
        public static readonly int cyclesToReadOneByte = 5;
        public static readonly int cyclesToWriteOneByte = 5;
        public static readonly int ProcessorCount = 8;

        public static readonly Func<int, int> Rc = bytes => cyclesToReadOneByte * bytes;    //Read communication overhead (bytes -> cycles)
        public static readonly Func<int, int> Wc = bytes => cyclesToWriteOneByte * bytes;   //Write communication overhead (bytes -> cycles)

        private static Dictionary<string, int> communicationCosts = new Dictionary<string, int> {
            { "int", 4 },
            { "double", 8 },
            { "bool", 1 },
            { "char", 2 }
        };

        public static int FromTextValue(string value) {
            return communicationCosts["char"] * value.Length;
        }

        public static int Get(string type) {
            return communicationCosts[type];
        }
    }

    class Nodes
    {
        private static Dictionary<FullCellAddr, SisalNode> nodes = new Dictionary<FullCellAddr, SisalNode>();

        public static bool ContainsKey(FullCellAddr fca) {
            return nodes.ContainsKey(fca);
        }

        public static void Add(FullCellAddr fca, SisalNode node) {
            nodes.Add(fca, node);
        }

        public static SisalNode Get(FullCellAddr node) {
            return nodes[node];
        }

        public static void PrintDictionary() {
            Console.WriteLine("- - - - - - - - - - - Dictionary - - - - - - - - - - - - -");

            foreach (var key in nodes.Keys) {
                Console.WriteLine("{0}: {1}", key, nodes[key]);
            }
        }

        public static void ClearDictionary() {
            nodes.Clear();
        }
    }
}
